It is not really the redundancy of ASCII, but the redundancy of that which is encoded with ASCII. Namely, you use ASCII because you encode sequences of characters, and you use characters because you want the data to be perceptible by human eyes and brains. So the data is text or something close enough (e.g. XML). Some characters will be more common than others. Some patterns will be used.
The whole idea of a reused one-time pad is that it transports information from one plaintext to the other: if you know 'A xor P' and 'B xor P' (A and B being the plaintext bytes, P the pad), then you can compute 'A xor B' by xoring the two values together. Then every bit of information you learn about A yields the corresponding information on B. For instance, if A is some XML text and you have already ascertained that some plaintext bytes are "<config
" then you can guess that the next byte of A will probably be a ">
", a space, or a "u
". These are three possible plaintext bytes, from which you can immediately deduce the only three possible plaintext bytes at the same position for B. Depending on what you know of B, you can prune out values which "make no sense", and thus know the byte value for A, and so on.
When breaking the infamous two-times pad, you just keep on propagating information from one plaintext to the other, and back.
ASCII already says quite a lot, because valid ASCII values are in the 0 to 127 range, but in "normal" text, a lot won't appear: in the 0 to 31 range, only 9 (tab), 10 (lf) and 13 (cr) will be encountered in practice.