I would probably do this in two passes. The first would convert the rectangles into a collection of points (in winding order), including the points where the corner of another rectangle is a point along an edge. That way you'll end up with a graph of points where you can easily detect which points are shared between which rectangles.
With that, just search your graph for the first point with no shared rects and start walking routes along points that have up to no shared rects, or two shared rects where the previous point has no shared rects, until you get back to the starting point.
You'll need to maintain a stack for your route, as well as a map of previously explored points.
I did exactly this just recently (although it wasn't limited to rects and I already had the first pass done) and it worked quite nicely. I was seeing it able to calculate a route in a graph of about 30 points more times in a second than I could count in an int, so performance seemed pretty good, although that was in C++.