Tried D 1.0? I reasoned the same way, and spent a lot of time coding D. In the end, I had to admit that a staggering percentage of bugs in my code came from just this. Deleting objects where a reference had leaked somewhere, deleting objects from the GC-called destructor of an object, mixing manage and non-managed objects a bit too freely ...
For D 2.0 I think most of that is rewritten, but I haven't bothered due to some sour experiences in D 1.0, and a slight dislike for some Phobos API:s and project management.
Basically IMHO for non-GC, simple memory management, I think language features for tracking ownership and the mindset that comes with it is necessary. For example, just like you have argument-modifiers for immutable arguments in some languages (C++ const), so I think you should have an argument modifier saying "you do not own this referenced object, and you are obliged to not remember the reference after return;".
Rust seems to have some interesting ideas regarding this, but I haven't really tried it for anything non-trivial.
In the end, I do most of my systems-level coding in C++ again. It's far from ideal, but it works, and with the smart-ptr classes available now, it's lack of GC is mostly a non-issue.
An interesting side-effect of the C++ helpers for deterministic object lifetimes, is the ability to tie resources (more scare than RAM) to the lifetimes of the objects. For example, keeping a file-struct as a member in a class will hold the file open for the lifetime of the class, but automatically ensure it is closed when the class is. In for example Java, you may very well run out of file-handles before the GC even kicks in and looks for objects to kill.