Scheme and Haskell have other primitives that take the place of while and goto.
But yes, using more expressive match types or parameters is a good idea. As for providing the result as an argument, that can be a good pattern, but isn't always practical. Note what I said in my original comment about using your own discretion.
(At least for C as encountered in the wild, I don't know about C the standard.)
Most modern C compilers support tail call optimization.
I don't know about `most languages'. Eg I know Java on the JVM doesn't do tail call optimization. Lots of languages probably do not require TCO of their implementations, though.