declaring two dimensional char arrays to used as strings.

Trying to get away from String objects, google is providing more confusion than answers (because I am easily confused)

I have this declaration using the String object array....

String Message[] = {"Happy Holidays",
                    "Some men are Baptists, others Catholics. My father was an Oldsmobile man.",
                    "In our world, you were either a bully, a toady, or one of the nameless rabble of victims!",
                    "BB Gun mania knows no loyalty.",
                    "NADDAFINGA!!",
                    "Eat, drink and be merry for tomorrow you may diet",
                    "He looks like a deranged Easter Bunny.",
                    "Didn't I get a tie this year?",
                    "SONS O' B&*&^$#@ES! BUMPUSES!!!",
                    "I can't put my arms down!"
                   };

How do I modify this to use as a two deminsional array of char? I want to submit it to a function such as...displayMessage(Message[n])    // n indicates which message

....so I also need to understand what the function declaration would look like. Do I need to use pointers to do that. I am still very weak on pointers.

I was using Strings but they seem to bite me and it was suggested that I learn to use the standard array of char for strings. I have googled quite a bit on this and find that there are many roads to Rome and I seem to be getting lost in them.

Like this. Ensure that the size will hold your longest char array and includes an extra char for the terminating null character:-

char message[# of elements][size of elements];

A small example:-

char message[4][5]=
{
    "msg1",
    "msg2",
    "msg3",
    "msg4"
};

void displayMessage(byte msgNum)
{
    Serial.println(message[msgNum]);
}

void setup()
{
    Serial.begin(115200);
    displayMessage(2);            // Prints "msg3" to the serial monitor.
}

void loop(){}

This is a big topic - the interactions between arrays and pointers is one of the main things that C programmers need to grok.

The short answer is:

void displayMessage(byte *msg)
{
    Serial.println(msg);
}

The longer answer is:

Whenever you actually use an array, whenever you reference a value in it, the value of the array name is treated as being a pointer to the first element in the array - element zero.

So int foo[5] is an array of five ints, but whenever you use "foo" in an expression, it's exactly the same as using a pointer to int - the compiler subs in the value of the memory address where foo happens to be put.

In C, a string is an array of char values terminated with a nul - '\0'. But whenever you use such an array, what gets passed around the shop is a pointer to char.

So lets say you have two arrays:

char[][5] foo = { "foo", "bar", "baz" };
char *bar[] = { "foo", "bar", "baz" };

In the first instance, the compiler allocates 15 bytes in memory somewhere and lays them out like so

100: f,o,o,0,0,b,a,r,0,0,b,a,z,0,0

In the second, the compiler lays out three sets of 4 bytes, one for each string, and lays out space for an array of three pointers to char. Each of these pointers is initialized to point at its string.

100: f,o,o,0
104: b,a,r,0
108: b,a,z,0
10C: 01, 00, 04, 01, 08, 01 (pretending that pointers are two-byte little-endian)

When you dereference bar like this: message(bar[2]), you get a pointer to char - the memory address of the 'b' in baz (108) . Like so:
bar - value 10C, type pointer to pointer to char
add 2 * sizeof(pointer to char), result 110 (pointer to pointer to char)
dereference. Get the pointer we are ponting at - fetch the value at 110 - result 108

When you dereference foo like this: message(foo[2]), you also get a pointer to char, but its a bit more complicated.

foo - 100, type pointer to array of 5 char
add 2 * sizeof(pointer to array of 5 char), result 10A (pointer to array of 5 char)
dereference. Get the array we are pointing at. The array is the array of 5 char at 10A, so all we need to do is treat that memory location as a pointer to the first element of that array. Result is still 10A.

Sorry about how unclear this explanation is. Like so many things, once you get it, it's simple. And it's a key feature of the C programming language - so many idioms rely on this correspondence that you won't be able to read C written by someone who does understand it until you do.