Here is one way of doing this. I give a brief explanation of what each method is doing and also included some comments. Note that I have not included any error handling.

FindCharacters

private static List<string> FindCharacters(List<string> characters, string sentence)
{
var output = new List<String>();
var wordIndex = 0;
// Iterate around each word
foreach (var word in sentence.Split(' '))
{
wordIndex++;
var tupleList = new List<Tuple<char, int>>();
// Iterate around each character
foreach (var character in characters)
{
// To get the index of the character it needs to be converted to an actual char
var parsedChar = char.Parse(character);
for (int i = word.IndexOf(parsedChar); i > -1; i = word.IndexOf(parsedChar, i + 1))
{
tupleList.Add(new Tuple<char, int>(parsedChar, i + 1));
}
}
// Build the output line for this word and add it to the list
output.Add(BuildLine(tupleList, wordIndex, word.Length));
}
return output;
}

This method takes the input and creates a List<string> containing each line of output required. It does so by iterating around each word in the sentence and then around each character, saving the character index information as a List<Tuple<char, int>>. This is then passed to the BuildLine method to generate the line of output for that word.

Here we are just using the tupleList we created along with wordLength and wordIndex to output the line for that word. There is also a check for the first and last words so that we know whether to include "where" or ",".