If you want to ignore such implementation details, you’re basically saying you want to see a language that doesn’t allow recursion, or maybe even one that allows recursion, but only in such a way that the compiler can compute the maximum amount of memory needed for activation records.
In a language that doesn’t allow recursion, using a call stack still can make sense for the implementation because it allows reuse of memory for local variables between functions that do not call each other, directly or indirectly.
But then, you’re giving up “plus weirdo stuff like the ability to hand out references to local data in functions that have already returned”, although, thinking of it, static analysis could make those locals survive by manipulating the stack pointer (if you have the caller allocate and, reallocate the locals of the called function, the caller can postpone that reallocation if it wants to access the locals of the called function). I’m not sure that weirdo stuff is worth the effort, though. It’s just a weird way to return multiple values from a function.