Entirely procedural, the foam pattern is a combination of Crust nodes (large to small bubbles) and the Crumple texture (used to fill in any remaining areas). Shading is a combination of subsurface scattering, blinn, and phong shaders using a combination of normals and inverted normals to create the bubble-like light interaction (rendering both front and back reflections simultaneously with only one surface). Backlighting can be coloured separately (visible in some of the development renders), but I decided I didn't like it as much in the final. Multi-coloured highlights are created using a rainbow gradient and several mixed inputs (incidence of bubble texture, noise pattern, etc.). Surface depth is computed using the Thickness node along with a fine grained noise pattern to break up the IOR input, simulating a softer falloff and diffused refraction. Reflection and refraction diffusion is controlled based on the simulated bubble density/size, allowing for larger bubbles to appear more clear, while the nearly-white areas are completely diffused (as you would also see, to some extent, in real foam).
The shading setup is based primarily around lights with minimal reflection and radiosity added in, but could be converted to 100% reflection+radiosity based lighting if needed by swapping out the specular shaders with reflection shaders. Would need further tweaking, but should work well enough.
The bubbles can be displaced individually, but it renders faster with just the simple geometry, and prevents further oddities with the inverted normals (which conflict with dramatically displaced bubbles, obviously). Subtle displacement can work well to break up geometry intersections, which are pretty harsh right now.
The biggest remaining issue is the shadowing from the simple foam object - it casts shadows only outside of itself, causing major discontinuities at the geometry boundary in darkened areas. I tried double-sided geometry at one point, but it didn't seem to help at the time. Will have to continue testing to figure out what's going on there.
Basic node setup took about an hour, with several hours spent tweaking and fine tuning some of the details (writing the full tutorial, on the other hand, took ~4 evenings and one Saturday afternoon!).