KNNImputer add_indicator fails to persist where missing data had been present in training

### Describe the bug

Hello, I've encountered an issue where the KNNImputer fails to record the fields where there were missing data at the time when `.fit` is called, but not recognised if `.transform` is called on a dense matrix. I would have expected it to return a 2x3 matrix rather than 2x2, with `missingindicator_A = False` for all cases.

Reproduction steps below. Any help much appreciated :)

### Steps/Code to Reproduce

```python
>>> import pandas as pd
>>> from sklearn.impute import KNNImputer
>>> knn = KNNImputer(add_indicator=True)
>>> df = pd.DataFrame({'A': [0, None], 'B': [1, 2]})
>>> df
     A  B
0  0.0  1
1  NaN  2
>>> knn.fit(df)
KNNImputer(add_indicator=True)
>>> pd.DataFrame(knn.transform(df), columns=knn.get_feature_names_out())
     A    B  missingindicator_A
0  0.0  1.0                 0.0
1  0.0  2.0                 1.0
>>> df['A'] = 0
>>> pd.DataFrame(knn.transform(df), columns=knn.get_feature_names_out())
```

### Expected Results

```
     A    B  missingindicator_A
0  0.0  1.0                 0.0
1  0.0  2.0                 0.0
```

### Actual Results

```pytb
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[30], line 1
----> 1 pd.DataFrame(knn.transform(df), columns=knn.get_feature_names_out())

File /opt/conda/lib/python3.10/site-packages/pandas/core/frame.py:694, in DataFrame.__init__(self, data, index, columns, dtype, copy)
    684         mgr = dict_to_mgr(
    685             # error: Item "ndarray" of "Union[ndarray, Series, Index]" has no
    686             # attribute "name"
   (...)
    691             typ=manager,
    692         )
    693     else:
--> 694         mgr = ndarray_to_mgr(
    695             data,
    696             index,
    697             columns,
    698             dtype=dtype,
    699             copy=copy,
    700             typ=manager,
    701         )
    703 # For data is list-like, or Iterable (will consume into list)
    704 elif is_list_like(data):

File /opt/conda/lib/python3.10/site-packages/pandas/core/internals/construction.py:351, in ndarray_to_mgr(values, index, columns, dtype, copy, typ)
    346 # _prep_ndarray ensures that values.ndim == 2 at this point
    347 index, columns = _get_axes(
    348     values.shape[0], values.shape[1], index=index, columns=columns
    349 )
--> 351 _check_values_indices_shape_match(values, index, columns)
    353 if typ == "array":
    355     if issubclass(values.dtype.type, str):

File /opt/conda/lib/python3.10/site-packages/pandas/core/internals/construction.py:422, in _check_values_indices_shape_match(values, index, columns)
    420 passed = values.shape
    421 implied = (len(index), len(columns))
--> 422 raise ValueError(f"Shape of passed values is {passed}, indices imply {implied}")

ValueError: Shape of passed values is (2, 2), indices imply (2, 3)
```

### Versions

```shell
python3, sklearn = 1.2.1
```

COMMENT:
We can fix it by concatenating with the indicator even if there's no missing values.
```
        # Removes columns where the training data is all nan
        if not np.any(mask):
            # No missing values in X
            if self.keep_empty_features:
                Xc = X
                Xc[:, ~valid_mask] = 0
            else:
                Xc = X[:, valid_mask]

            # Concatenate with the indicator even if there's no missing values
            return super()._concatenate_indicator(Xc, X_indicator)
```

test:

```
import pandas as pd
from sklearn.impute import KNNImputer
knn = KNNImputer(add_indicator=True)
input_df = pd.DataFrame({'A': [0, None], 'B': [1, 2]})
print('Input dataframe with missing values used in fit: \n',input_df)
knn.fit(input_df)
transformed_df = pd.DataFrame(knn.transform(input_df), columns=knn.get_feature_names_out())
print("input transformed \n",transformed_df)
print("\n\n-------------------\n\n")
df_with_no_missing_values = input_df.copy()
df_with_no_missing_values['A'] = 0
print("df with no missing values \n",df_with_no_missing_values)
df_with_no_missing_values_transformed = pd.DataFrame(knn.transform(df_with_no_missing_values),
                                                     columns=knn.get_feature_names_out())
print("df with no missing values after transformation\n",df_with_no_missing_values_transformed)
```

output

```
Input dataframe with missing values used in fit: 
      A  B
0  0.0  1
1  NaN  2
input transformed 
      A    B  missingindicator_A
0  0.0  1.0                 0.0
1  0.0  2.0                 1.0


-------------------


df with no missing values 
    A  B
0  0  1
1  0  2
df with no missing values after transformation
      A    B  missingindicator_A
0  0.0  1.0                 0.0
1  0.0  2.0                 0.0
```

Labels: Bug