First, read this post from Eric Lippert on The Stack is an Implementation Detail. Follow it with The Truth about Value Types.
As for your specific question
Are struct instances sometimes allocated on the heap?
Yes, they are sometimes allocated on the heap. There are lots of examples of when they could be allocated on the heap. If they are boxed, or if they are fields in a class, or if they are elements of an array, or if they are the value of a variable of value type that has been closed over, etc.
But what happens if I place the struct-values in a list and return that? The elements survives.
You're thinking about this the right way, and this is one of the salient points on where a value type might be allocated. See the second post that I referred to on The Truth About Value Types for more details. But just keep The Stack is an Implementation Detail in mind. The key takeaway is that you really don't need to concern yourself with this stuff. You should be concerned with the semantic difference between value types and reference types.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…