A more intuitive, hand-wavy version of zra's proof:
It obviously works when there's no loop.
Now, assume the slow pointer enter the looping part. Since it's a loop, we can see it as the slower pointer being ahead by some number of links. Then the faster pointer will reduce this distance by 1 link each step, until they meet. (And this will clearly take no longer than one "lap".)
zra generalized this e.g. to other pointer increments.