Instead of assigning the loop results to the input data, use is.na<- to assign NA values to elements given by function outliers.

remove_outliers <- function(data, cols = names(data)) {
  for (col in cols) {
    is.na(data[[col]]) <- outliers(data[[col]])
  }
  data
}

Note

The following function does exactly the same as function outliers but is a much simpler one-liner.

outliers2 <- function(x) x %in% boxplot.stats(x)$out

s1 <- lapply(names(data), \(x) outliers(data[[x]]))
s2 <- lapply(names(data), \(x) outliers2(data[[x]]))
identical(s1, s2)
#[1] TRUE