If you don't actually care about using String.Join but only want the result, using new string(char[]) is the simplest change:
string message = "This is a test message.";
var nonLetters = message.Where(x => !Char.IsLetter(x));
Console.WriteLine("There are {0} non-characters in \"{1}\" and they are: {2}",
nonLetters.Count(),
message,
new string(nonLetters.ToArray()));
but for your example it is more efficient if you do it this way:
string message = "This is a test message.";
string nonLetters = new string(message.Where(x => !Char.IsLetter(x)).ToArray());
Console.WriteLine("There are {0} non-characters in \"{1}\" and they are: {2}",
nonLetters.Length,
message,
nonLetters);
The reason this is more efficient is that the other example iterates your where iterator twice: Once for the Count() call and the other time for the ToArray() call.