Most purely functional languages (like Haskell) don't really have a "call stack", but the computation is carried out by graph reduction, so it can obviously detect cycles and do some optimizations there, depending on the type of recursion.
If you want the gory details https://www.microsoft.com/en-us/research/wp-content/uploads/...