Is this the most efficient way to track word changes in a string?
Ruby is fundamentally more about simplicity (readability) than about time/memory efficiency. Otherwise you should choose another language. There are such high level languages, that can beat Ruby, like for example Javascript. And even Python handle strings faster than Ruby at the cost of eternal problems with encodings (don't waste your time on crutches, choose tools wisely).
And even inside Ruby single replacements of one method chain with another can either be efficient or not, depending on your platform (jruby? rubinius? etc.) while there are still different ways to measure an algorithmic complexity especially for your unique kind of input data.

So anyway.


The matrix creation I would write in one of these two ways:

matrix = (0..second.size).map{ |i|
  (0..first.size).map{ |j|
    i==0 ? j : j == 0 ? i : 0
  }
}

matrix = (0..second.size).map{ |i|
  i==0 ? (0..first.size).to_a : [i]+[0]*first.size
}


There is also a solution via transpose, but not functional, and one via zip in which I doubt.
You can omit the return keyword at the last line in Ruby functions.


And this is not Ruby-related, but in the main loop try to iterate through 0...second.length instead of 1..second.length (same for first). In that way you'll swap i-1 with i and i with i+1, getting rid of two decrements in total.