Compiling all Exception messages into a string
Readability first


  I've tried to condense everything to one line, but am unsure if this is the most efficient way of approaching this problem.


Your primary goal when writing code is readability and maintainability and not squeezing everything into single lines.



Can you read this?


return exception != null ? string.Format("{0}: {1}\n{2}", msgCount, exception.Message, GetExceptionMessages(exception.InnerException, ++msgCount)) : string.Empty;



I cannot. This line is way too long even on my large monitor.

How about this? A little bit better, but still, the third line is too long even with string interpolation instead of string.Format

return
    exception is null
        ? string.Empty
        : $"{messageCount}: {exception.Message}{Environment.NewLine}{GetExceptionMessages(exception.InnerException, ++messageCount)}";




Separation

We need to change the strategy because your method is doing two things at a time:


it's looking for exceptions and
it's building a string


We need to separate them by implementing an extension that will enumerate exceptions:

public static IEnumerable&lt;Exception&gt; DescendantsAndSelf(this Exception exception)
{
    do
    {
        yield return exception;
        exception = exception.InnerException;
    } while (!(exception is null));
}


Then we rewrite the string building method as an extension of the first one:

public static string StringifyMessages(this IEnumerable&lt;Exception&gt; exceptions)
{
    var messages = exceptions.Select((e, i) =&gt; $"{i + 1}: {e.Message}")
    return string.Join(Environment.NewLine, messages);
}


So, finally you can chain them like this:

catch (Exception e)
{
    Console.WriteLine(e.DescendantsAndSelf().StringifyMessages());
}




Advantages

This means more code now but this code is testable, modular and can be reused for other things and extensions.