You've got two issues that sum to the same problem: Creating and discarding mutated copies of the string, while leaving the original untouched. str.replace must be assigned somewhere to be useful (usually reassigning word in this case), but also, to update the original list, you must reassign that index in the list (word is a separate alias to the object in the list, but reassigning word just rebinds word and breaks the aliasing, it doesn't change the contents of the list). So the solution is:
- Keep the results from each replaceoperation
- Put the final result back into the listat the same location
The minimalist modification to your code that achieves this result while still following the same basic design is:
from itertools import count  # So we can track the index to perform replacement at
def redact_words(sentence):
    redacted_sentence = sentence.split()
    for i, word in zip(count(2, 3), redacted_sentence[2::3]):  # Track index and value
        for c in set(word):  # Change name to c; i is for indices, not characters/letters
                             # For minor efficiency gain, dedupe word so we don't replace same char over and over
            if c.isalpha():
                word = word.replace(c, '#')  # Reassign back to word so change not lost
        redacted_sentence[i] = word  # Replace original word in list with altered word
    return " ".join(redacted_sentence)
A faster solution would replace the inner loop with a single-pass regex substitution or (if only ASCII need be handled) str.translate call, replacing O(n²) work per word with O(n) work, e.g.:
import re
from itertools import count  # So we can track the index to perform replacement at
# Precompile regex that matches only alphabetic characters and bind its sub method
# while we're at it    
replace_alpha = re.compile(r'[^\W\d_]').sub
def redact_words(sentence):
    redacted_sentence = sentence.split()
    for i, word in zip(count(2, 3), redacted_sentence[2::3]):  # Track index and value
        # Replace every alphabetic character with # in provided word and replace
        # list's contents at same index
        redacted_sentence[i] = replace_alpha('#', word)
    return " ".join(redacted_sentence)