I can relate to many points. I made a lisp (a scheme) as a scripting language for my game dev purposes, and went through many of the same phases. I really wanted continuations in my scripts (super useful for sequencing things over time across multiple frames, which is mostly what games do). So I had to get comfortable with cps style. But oh, it blows up the stack. But what if I had my own stack?
What I have currently is very close to the stack interpreter described in the fantastic paper Three Implementation Models for Scheme, while initially it was built iteratively based on Lisp in Small Pieces. Though I don't use "real" continuations, just an "await", "race" etc. which is just syntactic sugar that is easy to implement once there is a cps conversion in place. There are some important optimizations that can't be done (or are really hard to prove) if there are real continuations. For example, who knows if a closure can be magically re-entered if the language basically supports goto? Better not put it on the stack, even if it seems like it won't escape the scope.