Волновой алгоритм. Не уверен, как сделать что-то вроде std::vector / std::queue в паскале, но допустим есть у вас класс, позволяющий добавлять в конец списка элемент и "выталкивать" элемент с начала списка. И допустим есть у вас класс "точка" - ради сохранения координат клетки (строка, столбец). Пускай в матрице M пустая клетка имеет значение 0, а не пустая - свой номер.
Алгоритм следующий:
// прошу прощения за Сишные выражения в некоторых местах =)
stack := [];
for (y := 0 to rows) do
begin
for (x := 0 to columns) do
begin
if (M[y][x] != 0) then // клетка не пуста
begin
stack.push(Point(x, y));
break;
end;
// нашли первую не пустую клетку
if (stack.size() > 0) then
break;
end;
// для связи предыдущей и текущей клеток
Point previous := null;
while (stack.size() > 0) do
begin
Point p := stack.pop(); // достаем из стека координаты первой клетки, от которой будем "плясать"
// ищем вокруг "пляшущей" клетки все, от которых можем плясать
if (M[p.y + 1][p.x] != 0) then stack.push(Point(p.x, p.y + 1);
if (M[p.y - 1][p.x] != 0) then stack.push(Point(p.x, p.y - 1);
if (M[p.y][p.x + 1] != 0) then stack.push(Point(p.x + 1, p.y);
if (M[p.y][p.x - 1] != 0) then stack.push(Point(p.x - 1, p.y);
// случай с перой найденной клеткой
if (previous != null) then
begin
File.WriteLine(M[previous.y][previous.x], ' ', M[p.y][p.x]);
end;
previous := p;
end;