Shortcode return $content vs do_shortcode($content)

This is useful if you don’t know if the $content contains unknown shortcodes.

Example

Your shortcode

add_shortcode( 'foo', 'shortcode_foo' );

function shortcode_foo(  $atts, $content="" )
{
    return 'Foo!' . do_shortcode( $content );
}

Now your user might write something like this:

[foo][bar][/foo]

You have no idea what [bar] does or that it even exists. So you let WordPress handle that per do_shortcode(). If you don’t do that, [bar] will not be parsed as shortcode and showed as is instead.