What are healthy, productive ways to encourage students to progress to more advanced constructs as opposed to staying with the familiar?
I'm afraid that there is no single silver bullet.  The problem you've pointed to is very real, and isn't limited to students.  All of us tend to stick to our own familiar toolsets because, well, it's easier.  We know how to use them already.  

Enter the Motivating Example.  This mythical thing makes a new topic so useful that the new topic is practically a requirement.  Want to motivate recursion?  Try having kids determine the file-size of a folder (including its sub-folders).  Want to motivate methods?  Try giving a main method that calls them, and ask the kids to create the code that will make everything work.

Finding a great, motivating example feels like a search for hidden treasure; it is painful and slow.  You're seeking something of great value, and it's hard to know where to look.  To make matters worse, a good motivator for one teacher may not work for another, because what makes a motivating example work is intricately tied into both the broader curriculum and what sorts of things the teacher emphasizes within the classroom.

And once found, they are indeed treasures!  Clean, motivating examples make the value of a topic immediately apparent to students.  Resistance melts away, and is replaced by enthusiasm for the new tool that is now making their life easy.

Sometimes I spend weeks trying to find a good motivator.  I've found that teacher communities (such as this very one!) can be great sources of inspiration for them, as can algorithms books.  Or, as Kevin pointed out in a comment (before it was deleted):


  As far as finding motivation is concerned, it may be helpful to look into the history of the construct. For example, foreach used to be called "the iterator pattern," and even appears in the GoF book under that name, before there even was a foreach loop. So foreach isn't about simplifying the code so much as it is about abstracting away the implementation details of "get the size of the container" and "get the nth element" into a single opaque accessor. That suggests that a motivating example might begin by introducing trees, showing traversal code, and then contrasting it with an array.


Even with all of these tools, there are no easy guarantees. I sometimes have to simply wait for my "Eureka!" moment, and teach the best I can in the meantime.